/**
@file
	MassiveConnectionDevice.h
@brief
	Interface of MassiveConnectionDevice.
@author
	GengYong
@revision
	2005/10/27 * Created by GengYong.
*/

#ifndef MMONETWORK_HEADERFILE_MASSIVECONNECTIONDEVICE_H
#define MMONETWORK_HEADERFILE_MASSIVECONNECTIONDEVICE_H

#include "mmoSocket.h"
#include "mapper.h"

namespace MMONetwork
{
	namespace Server
	{
		typedef struct ConnEntity
		{
			unsigned long  node;
			unsigned short group;
			unsigned short routine;
		} ConnEntity;


		typedef struct MessageEntity
		{
			unsigned short	seg;
			unsigned short  cmd;
			void		*	buf;
			unsigned long	len;
			unsigned long	time;
		} MessageEntity;

		typedef struct AppendBuffer
		{
			void		*	buf;
			unsigned long	len;
		} AppendBuffer;

		typedef struct FluxInfo
		{
			unsigned long long	in_bytes;
			unsigned long long	out_bytes;
			unsigned long long	in_packets;
			unsigned long long	out_packets;
			unsigned long	active_time;
			unsigned long	capture_time;
		} FluxInfo;

		class MassiveConnectionDevice
		{
		public:
			enum
			{
				DEV_CONNECTION_CREATE,
				DEV_CONNECTION_DESTROY,
				DEV_CONNECTION_BROKEN
			};
		public:
			typedef struct BuildParam
			{
			public:
				BuildParam():
				MaxConnections(32),
				MaxMessages(32768),
				SendBufLength(65536),
				RecvBufLength(65536),			
				RecvTimeout(10),
				SendTimeout(0)
				{;}
			public:
				unsigned long MaxConnections;
				unsigned long MaxMessages;
				unsigned long SendBufLength;
				unsigned long RecvBufLength;			
				unsigned long RecvTimeout;
				unsigned long SendTimeout;
			} BuiltParam;

		private:
			typedef struct MessageDescriptor
			{
				void *			key;
				MessageEntity	msge;
				ConnEntity		conn;
			} MessageDescriptor;

			typedef struct ConnectionDescriptor
			{
				unsigned long long	flux_in_bytes;
				unsigned long long  flux_out_bytes;
				unsigned long long	flux_in_packets;
				unsigned long long	flux_out_packets;
				unsigned long	flux_active_time;
				unsigned long	send_left;
				unsigned long	recv_left;
				unsigned long	bytes_sent;
				unsigned long	bytes_recv;
				in_addr			remote_addr;
				void *			key;
				char *			send_ptr;
				char *			recv_ptr;
				char *			proc_ptr;
				SOCKET			sock;
				unsigned long	node;
				unsigned short	group;
				unsigned short	reserved0;
				char			is_listen;
				char			is_recvblocked;
				char			overflowed_count;
				char			reserved1;
			} ConnectionDescriptor;

		public:
			MassiveConnectionDevice();
			virtual ~MassiveConnectionDevice();
		public:
			bool Build(const MassiveConnectionDevice::BuildParam & param);
			void Destroy();
		public:
			bool CreateNode(unsigned short group, unsigned long node, const char * local_ip, unsigned short listen_port, void * key);
			bool AppendNode(unsigned short group, unsigned long node, const char * node_ip, unsigned short port, void * key);
			bool RedirectNode(unsigned short group, unsigned long node, const char * redirect_ip, unsigned short redirect_port);
			void RemoveNode(unsigned short group, unsigned long node, bool broken = false);
			bool ExistNode(unsigned short group, unsigned long node);
			bool MoveNode(unsigned short group, unsigned long node, unsigned short new_group, unsigned long new_node);
			bool LockNode(unsigned short group, unsigned long node, bool locked);
			bool BindNodeKey(unsigned short group, unsigned long node, void * key);
			unsigned long GetNodeIP(unsigned short group, unsigned long node);
			unsigned long GetNodeCount(unsigned short group);
			bool GetFluxInfo(unsigned short group, unsigned long node, FluxInfo *);
			bool GetFluxInfo(FluxInfo *);
		public:
			bool SendNetMessage(const ConnEntity&, const MessageEntity &, AppendBuffer * append = NULL, unsigned long append_count = 0);
			bool RecvNetMessage(ConnEntity &, MessageEntity &, void ** lpkey);	
		private:		
			void		 _RaiseMessage(const ConnEntity& conn, const MessageEntity& msge, void * key);
			bool		 _InsertNode(unsigned short group, unsigned long node, SOCKET sock, in_addr & addr, void * key, bool is_listen = false);
		private:
			Utility::mapper<MassiveConnectionDevice::ConnectionDescriptor*>		* m_Node2ConnMapper[1];
			Utility::mapper<MassiveConnectionDevice::ConnectionDescriptor*>		* m_Sock2ConnMapper;
			Utility::mapper<MassiveConnectionDevice::ConnectionDescriptor**>	* m_Sock2SendListMapper;
			Utility::mapper<MassiveConnectionDevice::ConnectionDescriptor**>	* m_Sock2RecvListMapper;
			MassiveConnectionDevice::MessageDescriptor		*		m_MsgDescBuf;		/* sizeof(MessageDescriptor) * MaxMessages */
			MassiveConnectionDevice::ConnectionDescriptor	*		m_ConnDescBuf;		/* sizeof(ConnectionDescriptor) * MaxConnections */
			MassiveConnectionDevice::ConnectionDescriptor	**		m_ConnDescUnused;	/* sizeof(ConnectionDescriptor*) * MaxConnections */
			MassiveConnectionDevice::ConnectionDescriptor	**		m_SendConnListBuf;	/* sizeof(ConnectionDescriptor*) * MaxConnection */
			MassiveConnectionDevice::ConnectionDescriptor	**		m_RecvConnListBuf;	/* sizeof(ConnectionDescriptor*) * MaxConnection */
			SOCKET		*	m_SelectBuffer;									/* sizeof(unsigned int) + sizeof(SOCKET) * MaxConnections */
			void		**	m_SendBuffers;									/* (sizeof(void*) + SendBufLength) * MaxConnections */
			void		**	m_RecvBuffers;									/* (sizeof(void*) + RecvBufLength * 2) * MaxConnections */
			char		*	m_BasePointer;
			unsigned long	m_MaxConnections;
			unsigned long	m_MaxMessages;
			unsigned long	m_SendBufLength;
			unsigned long	m_RecvBufLength;
			unsigned long	m_MsgDescCursor;
			unsigned long	m_MsgProcCursor;
			unsigned long	m_MsgCursor;
			unsigned long	m_ConnDescUnusedCursor;
			unsigned long	m_SendConnCursor;
			unsigned long	m_RecvConnCursor;
			unsigned long long	m_FluxInBytes;
			unsigned long long	m_FluxOutBytes;
			unsigned long long	m_FluxInPackets;
			unsigned long long	m_FluxOutPackets;
			unsigned long	m_FluxActiveTime;
			timeval			m_SendTimeout;
			timeval			m_RecvTimeout;
		};
	}
}



#endif	//#ifndef MMONETWORK_HEADERFILE_MASSIVECONNECTIONDEVICE_H
